package cn.web;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import org.springframework.jdbc.core.JdbcTemplate;

import javax.annotation.Resource;

@Component("baseService")
@Transactional
public class BaseService {
	/*
	 * BaseService被所有的服务继承，基本的Model对象可以使用这个操作
	 * 对于需要JdbcTemplate这个便利的使用jdbcTemplate成员操作
	 */
	//@Resource(name="jdbcTemplate")
	@Autowired
	public JdbcTemplate jdbcTemplate;

	@Autowired
	public BaseDao baseDao;

	private static BaseService baseService = null;

	public BaseService() {
		if (baseService == null) {
			baseService = this;
		} else {
			this.baseDao = baseService.baseDao;
			this.jdbcTemplate = baseService.jdbcTemplate;
		}
	}

	public JdbcTemplate getJdbcTemplate() {
		return this.jdbcTemplate;
	}
	
	/**
	 * 注入环境中，可以直接使用baseService
	 * 
	 * @return
	 */
	public static BaseService getBaseService() {
		return baseService;
	}

	public <T> List<T> getAll(Class<T> clazz) {
		return this.baseDao.getAll(clazz);
	}

	public <T> void deleteById(Class<T> clazz, Serializable id) {
		this.baseDao.deleteById(clazz, id);
	}

	public <T> void deleteByIds(Class<T> clazz, Serializable[] ids) {
		this.baseDao.deleteByIds(clazz, ids);
	}

	// 以前的保存照顾一下，省的再改，所以2个形式的保存接口
	public <T> Serializable add(T entity) {
		return this.baseDao.save(entity);
	}

	public <T> Serializable save(T entity) {
		return this.baseDao.save(entity);
	}

	@Transactional
	public void addBatch(Collection<?> list) {
		for (Object object : list) {
			this.baseDao.save(object);
		}
	}

	public <T> long getTotal(Class<T> clazz) {
		return this.baseDao.getTotal(clazz);
	}

	public <T> List<T> getByPage(Class<T> clazz, int offset, int limit) {
		return this.baseDao.getByPage(clazz, offset, limit);
	}

	/**
	 * 
	 * @param start
	 *            起始位置 从1开始
	 * @param max
	 *            最多获取的行数
	 * @return
	 */
	@Transactional(readOnly = true)
	public <T> List<T> getBySize(Class<T> t, int start, int max, Criterion... criterions) {
		return this.baseDao.queryForList(t, start - 1, max, null, criterions);
	}

	@Transactional(readOnly = true)
	public <T> List<T> getBySize(Class<T> t, int start, int max, Order order, Criterion... criterions) {
		return this.baseDao.queryForList(t, start - 1, max, order, criterions);
	}

	@Transactional(readOnly = true)
	public <T> List<T> queryForList(String hql, Object... objects) {
		return baseDao.queryForList(hql, objects);
	}

	@Transactional(readOnly = true)
	public <T> T getFirst(Class<T> t, Criterion... expressions) {
		return baseDao.getFirst(t, null, expressions);
	}

	@Transactional(readOnly = true)
	public <T> List<T> queryForList(Class<T> t, Criterion... expressions) {
		return baseDao.queryForList(t, null, expressions);
	}

	@Transactional(readOnly = true)
	public <T> List<T> queryForList(Class<T> t, Order order, Criterion... expressions) {
		return baseDao.queryForList(t, order, expressions);
	}

	@Transactional(readOnly = true)
	public <T> T getById(Class<T> t, Serializable id) {
		return (T) this.baseDao.getById(t, id);
	}

	@Transactional
	public void delete(Object objet) {
		this.baseDao.delete(objet);
	}

	@Transactional
	public void update(Object objet) {
		this.baseDao.update(objet);
	}

	/**
	 * 分页查询
	 *
	 * @param t
	 * @param pageSize
	 * @param pageNo
	 *            页数从1开始
	 * @param criterions
	 * @return
	 */
	@Transactional(readOnly = true)
	public <T> Page<T> getPage(Class<T> t, Integer pageNo, Integer pageSize, Criterion... criterions) {
		Page<T> page = new Page<T>();
		page.setCount(this.baseDao.getTotal(t, criterions));
		page.setLists(this.baseDao.queryForList(t, (pageNo - 1) * pageSize, pageSize, null, criterions));
		return page;
	}

	@Transactional(readOnly = true)
	public <T> Page<T> getPage(Class<T> t, Integer pageNo, Integer pageSize, Order order, Criterion... criterions) {
		Page<T> page = new Page<T>();
		page.setCount(this.baseDao.getTotal(t, criterions));
		page.setLists(this.baseDao.queryForList(t, (pageNo - 1) * pageSize, pageSize, order, criterions));
		return page;
	}

	@Transactional(readOnly = true)
	public <T> T queryForUnique(Class<T> t, Criterion... expressions) {
		return this.baseDao.queryForUnique(t, expressions);
	}

	@Transactional(readOnly = true)
	public <T> T queryForUnique(String hql, Object... objects) {
		return this.baseDao.queryForUnique(hql, objects);
	}

	@Transactional
	public void saveOrUpdate(Object object) {
		this.baseDao.saveOrUpdate(object);
	}

	@Transactional
	public void execHql(String hql, Object... objects) {
		this.baseDao.execHql(hql, objects);
	}

	@Transactional
	public void execBatchHql(String... hqls) {
		for (String hql : hqls) {
			this.baseDao.execHql(hql);
		}
	}

	@Transactional
	public void execute(String sql){
		this.jdbcTemplate.update(sql);
	}

	@Transactional
	public void execute(String sql, Object... objects) {
		this.jdbcTemplate.update(sql, objects);
	}
}
